"""
应用程序设置管理

管理配置文件加载和应用程序设置。
"""

import yaml
from pathlib import Path
from typing import Dict, Any, Optional
from dataclasses import dataclass


@dataclass
class DataSourceConfig:
    """数据源配置"""
    projects_file: str
    resources_file: str
    tasks_file: str


@dataclass
class OutputConfig:
    """输出配置"""
    directory: str
    template_file: str
    filename_pattern: str


@dataclass
class AlgorithmConfig:
    """算法配置"""
    time_unit: str
    max_iterations: int
    optimization_target: str
    allocation_strategy: Dict[str, Any]
    conflict_resolution: Dict[str, Any]


@dataclass
class DisplayConfig:
    """显示配置"""
    date_format: str
    currency: str
    language: str
    excel_format: Dict[str, Any]


@dataclass
class ValidationConfig:
    """验证配置"""
    required_fields: Dict[str, list]
    data_constraints: Dict[str, Any]


@dataclass
class LoggingConfig:
    """日志配置"""
    level: str
    file: str
    format: str


class Settings:
    """应用程序设置类"""

    def __init__(self, config_file: Optional[str] = None):
        self.config_file = config_file or "config.yaml"
        self._config = {}
        self._load_config()

    def _load_config(self):
        """加载配置文件"""
        try:
            config_path = Path(self.config_file)
            if config_path.exists():
                with open(config_path, 'r', encoding='utf-8') as f:
                    self._config = yaml.safe_load(f) or {}
            else:
                # 使用默认配置
                self._config = self._get_default_config()
        except Exception as e:
            raise ValueError(f"加载配置文件失败：{e}")

    def _get_default_config(self) -> Dict[str, Any]:
        """获取默认配置"""
        return {
            "data_sources": {
                "projects_file": "data/input/projects.xlsx",
                "resources_file": "data/input/resources.xlsx",
                "tasks_file": "data/input/tasks.xlsx"
            },
            "output": {
                "directory": "data/output",
                "template_file": "Template/【公開用】PM_要員計画（山積み表・リソースヒストグラム）_20211121_01.xlsx",
                "filename_pattern": "【公開用】PM_要員計画（山積み表・リソースヒストグラム）_{date}_{version}.xlsx"
            },
            "algorithm": {
                "time_unit": "month",
                "max_iterations": 100,
                "optimization_target": "duration",
                "allocation_strategy": {
                    "prefer_skill_match": True,
                    "allow_overtime": False,
                    "max_workload_percentage": 100
                },
                "conflict_resolution": {
                    "auto_adjust_dates": True,
                    "priority_based": True,
                    "show_warnings": True
                }
            },
            "display": {
                "date_format": "%Y-%m-%d",
                "currency": "JPY",
                "language": "jp",
                "excel_format": {
                    "header_style": "bold",
                    "date_format": "yyyy-mm-dd",
                    "number_format": "#,##0"
                }
            },
            "validation": {
                "required_fields": {
                    "projects": ["project_id", "project_name", "start_date", "end_date"],
                    "resources": ["resource_id", "name", "role", "max_hours_per_week"],
                    "tasks": ["task_id", "project_id", "task_name", "estimated_hours"]
                },
                "data_constraints": {
                    "max_project_duration_months": 24,
                    "min_skill_level": 1,
                    "max_skill_level": 5,
                    "max_hours_per_week": 60
                }
            },
            "logging": {
                "level": "INFO",
                "file": "logs/auto_resource_plan.log",
                "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
            }
        }

    @property
    def data_sources(self) -> DataSourceConfig:
        """获取数据源配置"""
        config = self._config.get("data_sources", {})
        return DataSourceConfig(
            projects_file=config.get("projects_file", "data/input/projects.xlsx"),
            resources_file=config.get("resources_file", "data/input/resources.xlsx"),
            tasks_file=config.get("tasks_file", "data/input/tasks.xlsx")
        )

    @property
    def output(self) -> OutputConfig:
        """获取输出配置"""
        config = self._config.get("output", {})
        return OutputConfig(
            directory=config.get("directory", "data/output"),
            template_file=config.get("template_file", "Template/template.xlsx"),
            filename_pattern=config.get("filename_pattern", "resource_plan_{date}_{version}.xlsx")
        )

    @property
    def algorithm(self) -> AlgorithmConfig:
        """获取算法配置"""
        config = self._config.get("algorithm", {})
        return AlgorithmConfig(
            time_unit=config.get("time_unit", "month"),
            max_iterations=config.get("max_iterations", 100),
            optimization_target=config.get("optimization_target", "duration"),
            allocation_strategy=config.get("allocation_strategy", {}),
            conflict_resolution=config.get("conflict_resolution", {})
        )

    @property
    def display(self) -> DisplayConfig:
        """获取显示配置"""
        config = self._config.get("display", {})
        return DisplayConfig(
            date_format=config.get("date_format", "%Y-%m-%d"),
            currency=config.get("currency", "JPY"),
            language=config.get("language", "jp"),
            excel_format=config.get("excel_format", {})
        )

    @property
    def validation(self) -> ValidationConfig:
        """获取验证配置"""
        config = self._config.get("validation", {})
        return ValidationConfig(
            required_fields=config.get("required_fields", {}),
            data_constraints=config.get("data_constraints", {})
        )

    @property
    def logging(self) -> LoggingConfig:
        """获取日志配置"""
        config = self._config.get("logging", {})
        return LoggingConfig(
            level=config.get("level", "INFO"),
            file=config.get("file", "logs/auto_resource_plan.log"),
            format=config.get("format", "%(asctime)s - %(name)s - %(levelname)s - %(message)s")
        )

    def get(self, key: str, default: Any = None) -> Any:
        """获取配置值"""
        keys = key.split('.')
        value = self._config

        for k in keys:
            if isinstance(value, dict) and k in value:
                value = value[k]
            else:
                return default

        return value

    def set(self, key: str, value: Any) -> None:
        """设置配置值"""
        keys = key.split('.')
        config = self._config

        for k in keys[:-1]:
            if k not in config:
                config[k] = {}
            config = config[k]

        config[keys[-1]] = value

    def save(self, file_path: Optional[str] = None) -> None:
        """保存配置到文件"""
        save_path = file_path or self.config_file

        try:
            with open(save_path, 'w', encoding='utf-8') as f:
                yaml.safe_dump(self._config, f, default_flow_style=False,
                              allow_unicode=True, indent=2)
        except Exception as e:
            raise ValueError(f"保存配置文件失败：{e}")

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return self._config.copy()